﻿using System;
using System.Collections.Generic;
using System.Text;

namespace SharpSoft.Geometries
{
    /// <summary>
    /// 椭圆，使用外接矩形的起点坐标（离原点最近的顶点）和宽度高度描述的椭圆
    /// </summary>
    public struct Ellipse
    {
        public Ellipse(double x, double y, double w, double h)
        {
            X = x;
            Y = y;
            if (w < 0 || h < 0)
            {
                throw new ArgumentOutOfRangeException("椭圆的宽度和高度不能为负数。");
            }
            _Width = w;
            _Height = h;
        }
        /// <summary>
        /// 椭圆外接矩形的X坐标
        /// </summary>
        public double X { get; set; }
        /// <summary>
        /// 椭圆外接矩形的Y坐标
        /// </summary>
        public double Y { get; set; }

        private double _Width;
        /// <summary>
        /// 椭圆的宽度
        /// </summary>
        public double Width
        {
            get { return _Width; }
            set
            {
                if (value < 0)
                {
                    throw new Exception("宽度不能为负数。");
                }
                _Width = value;
            }
        }

        private double _Height;
        /// <summary>
        /// 椭圆的高度
        /// </summary>
        public double Height
        {
            get { return _Height; }
            set
            {
                if (value < 0)
                {
                    throw new Exception("高度不能为负数。");
                }
                _Height = value;
            }
        }

        /// <summary>
        /// 获取椭圆的中心点
        /// </summary>
        /// <returns></returns>
        public Point2D GetCenter()
        {
            return new Point2D(X + this.Width / 2, Y + this.Height / 2);
        }
        /// <summary>
        /// 椭圆是否包含指定的点。（点是否在椭圆内【包括椭圆边界】）
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public bool Contains(Point2D p)
        {
            var a = this.Width / 2;
            var b = this.Height / 2;
            var center = this.GetCenter();
            return (Math.Pow(p.X - center.X, 2) /
                Math.Pow(a, 2)) +
               (Math.Pow(p.Y - center.Y, 2) /
                Math.Pow(b, 2)) <= 1;
        }
    }
}
